package com.qcxy.gzy.activity.v4;

import android.os.Bundle;

import com.google.gson.Gson;
import com.qcxy.gzy.activity.base.BaseSwitchActivity;
import com.qcxy.gzy.bean.ComReceiveDataBean;
import com.qcxy.gzy.bean.SerialPortCommand;
import com.qxcy.gzy.util.PreferencesUtils;
import com.qxcy.gzy.util.SerialPortUtils;

import java.util.Timer;
import java.util.TimerTask;

/*
 * 此Activity主要用于切换电机
 * */
public abstract class SwitchEMActivity extends BaseSwitchActivity {
    //status当前流程状态
    //(-9-标识刹车启动命令已发送；-8-标识停止小电机命令已发送；
    //-7-标识停止大电机命令已发送；-6-标识打开大电机制动器命令已发送；
    //-5-标识启动大电机命令已发送；-4-标识停止刹车命令已发送；
    //-3-标识读电机状态命令已发送；
    //-2-标识刹车启动命令已发送；-1-标识旧电机进入等待命令已发(userRun->userWait)；
    //0-标识关闭旧电机制动器命令已发送；1-标识打开期望电机制动器命令已发送；
    //2-标识期望电机启动命令已发送（已启动则发送userWait->userRun）；3-标识读电机状态命令已发送；
    //4-标识刹车停止命令已发送；5-期望电机启动成功
    protected int needEMType;

    protected int brakeDelay = 120;//吸合制动器延时ms

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        resendCount = 3;
        builder = new StringBuilder();
        builder.append("------------------------------------------------------------------------\n");
        builderW("Test");
    }

    //切换到大电机
    protected void switchToEMBig() {
        showLoadingView();
        status = isEMRunning ? -2 : -9;
        needEMType = SerialPortUtils.ElectricMachineryBig;
        controlSC(SerialPortUtils.SCStart);
    }

    //切换到小电机
    protected void switchToEMSmall() {
        showLoadingView();
        status = isEMRunning ? -2 : -9;
        needEMType = SerialPortUtils.ElectricMachinerySmall;
        controlSC(SerialPortUtils.SCStart);
    }

    private void switchEM(@SerialPortUtils.ElectricMachineryType int emType) {
        if (isEMRunning) {
            builder.append("希望切换电机:").append(emType == SerialPortUtils.ElectricMachineryBig ? "大电机" : "小电机").append("\n");
            builderW("Test");
            //电机正在运行
            if (runEMType != emType) {
                status = -1;
                //发送电机进入等待命令
                controlEM(runEMType, SerialPortUtils.EMActionWait);
            }
        } else {
            builder.append("初始化-发送关闭小电机命令").append("\n");
            builderW("Test");
            status = -8;
            //发送小电机停止运行命令
            controlEM(SerialPortUtils.ElectricMachinerySmall, SerialPortUtils.EMActionStop);
        }
    }

    private void controlSC(@SerialPortUtils.SCAction int action) {
        builder.append("\n****************************刹车:").append(action == SerialPortUtils.SCStart ? "启动" : "停止").append("\n");
        builderW("Test");
        byte[] command = SerialPortUtils.getSCCommand(action);
        currentCommand = new SerialPortCommand(command, action == SerialPortUtils.SCStart ? SerialPortCommand.COM_TYPE_SC_START : SerialPortCommand.COM_TYPE_SC_STOP);
        sendCommand(currentCommand);
    }

    private void controlEM(@SerialPortUtils.ElectricMachineryType int emType, @SerialPortUtils.EMAction int action) {
        String actionName;
        switch (action) {
            case SerialPortUtils.EMActionStop:
                actionName = SerialPortCommand.COM_TYPE_EM_STOP;
                break;
            case SerialPortUtils.EMActionStart:
                actionName = SerialPortCommand.COM_TYPE_EM_START;
                break;
            case SerialPortUtils.EMActionWait:
                actionName = SerialPortCommand.COM_TYPE_EM_WAIT;
                break;
            case SerialPortUtils.EMActionRun:
                actionName = SerialPortCommand.COM_TYPE_EM_RUN;
                break;
            default:
                actionName = SerialPortCommand.COM_TYPE_EM_WAIT;
                break;
        }
        byte[] command = SerialPortUtils.getEMCommand(emType, action);
        currentCommand = new SerialPortCommand(command, actionName);
        sendCommand(currentCommand);
    }

    private void readEM(@SerialPortUtils.ElectricMachineryType int emType) {
        byte[] commandEMStatus = SerialPortUtils.getReadCommand(emType, SerialPortUtils.ReadEM);
        currentCommand = new SerialPortCommand(commandEMStatus, SerialPortCommand.COM_TYPE_EM_READ);
        sendCommand(currentCommand);
    }

    private void controlBrake(@SerialPortUtils.BrakeType int type, @SerialPortUtils.BrakeAction int action) {
        byte[] commandBrake = SerialPortUtils.getBradeCommand(type, action);
        currentCommand = new SerialPortCommand(commandBrake, action == SerialPortUtils.BrakeActionOpen ? SerialPortCommand.COM_TYPE_BRAKE_OPEN : SerialPortCommand.COM_TYPE_BRAKE_CLOSE);
        sendCommand(currentCommand);
    }

    //发送单条命令
    protected void sendCommand(SerialPortCommand command) {
        sendCommand(command, SerialPortUtils.SerialPortDefault);
    }

    /**
     * @param command   命令
     * @param delayTime 单位为10ms
     */
    protected void sendCommand(SerialPortCommand command, int delayTime) {
        if (resendThread != null) {
            resendThread.stopSend();
            resendThread = null;
        }
        resendThread = new autoResendThread(command, delayTime);
        new Thread(resendThread).start();
    }


    @Override
    protected void onDataReceived(final ComReceiveDataBean ComRecData) {
        builder.append("收到返回值1：").append(new Gson().toJson(ComRecData.bRec)).append("\n");
        builder.append("当前状态isSwitch：").append(isEMSwitching).append("\n");
        builderW("Test");
        w("收到:" + json(ComRecData.bRec));
        if (!isEMSwitching) return;
        dataParse(ComRecData);
    }

    protected boolean verification(final ComReceiveDataBean ComRecData) {
        switch (currentCommand.command[1]) {
            case SerialPortUtils.typeRead://读
                return ComRecData.getCRC(ComRecData.bRec).equals("0");
            case SerialPortUtils.typeWrite://写
                return ComRecData.bRec.length >= 5;//写操作只要返回数据长度>=5即为成功
            default:
                return true;
        }
    }

    protected void dataParse(final ComReceiveDataBean ComRecData) {
        if (verification(ComRecData)) {
            isCommandRun = false;
            if (resendThread != null) {
                resendThread.stopSend();
                resendThread = null;
            }
            switch (currentCommand.command[1]) {
                case SerialPortUtils.typeRead://读
                    if (ComRecData.bRec[1] == SerialPortUtils.typeRead) {
                        switch (status) {
                            case -3://初始化-读大电机状态
                                if (ComRecData.bRec[4] == 0x04) {
                                    updateEM(true, SerialPortUtils.EM_STATUS_RUN);
                                    builder.append("初始化-大电机启动且寄存器状态为启动-开启切换流程，发送启动刹车命令").append("\n");
                                    builderW("Test");
                                    isEMRunning = true;
                                    runEMType = SerialPortUtils.ElectricMachineryBig;
                                    //结束计时器
                                    stopTimer();
                                    PreferencesUtils.put(SwitchEMActivity.this, SerialPortUtils.EM_STATUS, true);
                                    updateEM(true, SerialPortUtils.EM_STATUS_RUN);
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            //开启切换流程，发送启动刹车命令
                                            switchToEMSmall();
                                        }
                                    });
                                } else {
                                    if (timeOutNum < readWaitTime) {
                                        //发送读电机状态命令
                                        readEM(SerialPortUtils.ElectricMachineryBig);
                                    }
                                }
                                break;
                            case 3:
                                if (ComRecData.bRec[4] == 0x04) {
                                    status++;
                                    builder.append("电机运行，发送刹车关闭命令").append("\n");
                                    builderW("Test");
                                    isEMRunning = true;
                                    runEMType = needEMType;
                                    //结束计时器
                                    stopTimer();
                                    PreferencesUtils.put(SwitchEMActivity.this, SerialPortUtils.EM_STATUS, true);
                                    updateEM(true, needEMType == SerialPortUtils.ElectricMachineryBig ?
                                            SerialPortUtils.EM_STATUS_RUN : SerialPortUtils.EM_STATUS_WAIT);
                                    updateEM(false, needEMType == SerialPortUtils.ElectricMachineryBig ?
                                            SerialPortUtils.EM_STATUS_WAIT : SerialPortUtils.EM_STATUS_RUN);
                                    //刹车关闭
                                    controlSC(SerialPortUtils.SCStop);
                                } else {
                                    if (timeOutNum < readWaitTime) {
                                        //发送读电机状态命令
                                        readEM(needEMType);
                                    }
                                }
                                break;
                        }
                    }
                    break;
                case SerialPortUtils.typeWrite://写
                    byte address = currentCommand.command[3];
                    byte action = currentCommand.command[5];
                    if (currentCommand.command[0] != SerialPortUtils.addressControl) {//电机操作返回
                        status++;
                        switch (action) {
                            case 0x01:
                                switch (status) {
                                    case -4://初始化-大电机启动成功
                                        builder.append("初始化-大电机启动成功，发送停止刹车命令已成功").append("\n");
                                        builderW("Test");
                                        //发送停止刹车命令
                                        controlSC(SerialPortUtils.SCStop);
                                        break;
                                    case 3:
                                        builder.append("期望电机启动成功，当前启动的电机为：").append(needEMType == SerialPortUtils.ElectricMachineryBig ? "大电机" : "小电机")
                                                .append("-发送读电机状态命令").append("\n");
                                        builderW("Test");
                                        //开启计时器
                                        timeOutNum = 0;
                                        startTimer();
                                        //发送读电机状态命令
                                        readEM(needEMType);
                                        break;
                                }
                                break;
                            case 0x00:
                                switch (status) {
                                    case -7://初始化-关闭小电机命令
                                        builder.append("初始化-小电机停止成功，发送大电机停止命令").append("\n");
                                        builderW("Test");
                                        //发送关闭大电机命令
                                        controlEM(SerialPortUtils.ElectricMachineryBig, SerialPortUtils.EMActionStop);
                                        break;
                                    case -6://初始化-关闭大电机命令
                                        builder.append("初始化-大电机停止成功，发送大电机制动器吸合命令").append("\n");
                                        builderW("Test");
                                        //发送大电机制动器吸合命令
                                        controlBrake(SerialPortUtils.BrakeForBig, SerialPortUtils.BrakeActionOpen);
                                        break;
                                }
                                break;
                            case 0x03:
                                if (status == 0) {
                                    updateEM(runEMType == SerialPortUtils.ElectricMachineryBig, SerialPortUtils.EM_STATUS_WAIT);
                                    //切换中-旧电机进入等待状态
                                    builder.append("切换中-旧电机:").append(runEMType == SerialPortUtils.ElectricMachineryBig ? "大电机" : "小电机")
                                            .append("-进入等待状态，发送旧电机制动器关闭命令").append("\n");
                                    builderW("Test");
                                    //发送旧电机制动器关闭命令
                                    controlBrake(runEMType, SerialPortUtils.BrakeActionClose);
                                }
                                break;
                            case 0x02:
                                if (status == 3) {
                                    builder.append("期望电机运行成功，当前运行的电机为：").append(needEMType == SerialPortUtils.ElectricMachineryBig ? "大电机" : "小电机")
                                            .append("-发送读电机状态命令").append("\n");
                                    builderW("Test");
                                    //开启计时器
                                    timeOutNum = 0;
                                    startTimer();
                                    //发送读电机状态命令
                                    readEM(needEMType);
                                }
                                break;
                        }
                    } else {//刹车与制动器操作返回
                        switch (address) {
                            case SerialPortUtils.addressSC://刹车（启动或者停止）命令返回数据
                                if (action == SerialPortUtils.SCStart) {
                                    switch (status) {
                                        case -9:
                                            builder.append("刹车启动成功，开始初始化").append("\n");
                                            break;
                                        case -2:
                                            builder.append("刹车启动成功，开始切换电机").append("\n");
                                            break;
                                    }
                                    builderW("Test");
                                    switchEM(needEMType);
                                } else {
                                    status++;
                                    switch (status) {
                                        case -3://初始化-刹车停止成功
                                            builder.append("初始化-刹车停止成功，发送读大电机状态命令").append("\n");
                                            builderW("Test");
                                            //开启计时器
                                            timeOutNum = 0;
                                            startTimer();
                                            //发送读大电机状态命令
                                            readEM(SerialPortUtils.ElectricMachineryBig);
                                            break;
                                        case 5://刹车停止成功
                                            builder.append("刹车停止成功").append("\n");
                                            builderW("Test");
                                            if (isImp()) {
                                                ((SwitchEMListener) SwitchEMActivity.this).onSwitch(true, "切换成功", runEMType);
                                            }
                                            break;
                                    }
                                }
                                break;
                            case SerialPortUtils.brakeStatusBig://大制动器（启动或者停止）命令返回数据
                            case SerialPortUtils.brakeStatusSmall://大制动器（启动或者停止）命令返回数据
                                status++;
                                switch (status) {
                                    case -5:
                                        builder.append("初始化-大电机制动器吸合成功，发送启动大电机命令").append("\n");
                                        builderW("Test");
                                        delayRun(new Runnable() {
                                            @Override
                                            public void run() {
                                                //发送大电机启动命令
                                                controlEM(SerialPortUtils.ElectricMachineryBig, SerialPortUtils.EMActionStart);
                                            }
                                        }, brakeDelay);
                                        break;
                                    case 1:
                                        builder.append("旧电机：").append(runEMType == SerialPortUtils.ElectricMachineryBig ? "大电机" : "小电机")
                                                .append("-制动器关闭成功，发送期望电机制动器启动命令").append("\n");
                                        builderW("Test");
                                        //发送期望电机制动器启动命令
                                        controlBrake(needEMType, SerialPortUtils.BrakeActionOpen);
                                        break;
                                    case 2:
                                        builder.append("打开制动器成功，当前打开的制动器为").append(needEMType == SerialPortUtils.ElectricMachineryBig ? "大电机制动器" : "小电机制动器").append("\n");
                                        builderW("Test");
                                        int x = needEMType == SerialPortUtils.ElectricMachineryBig ? emBigStatus : emSmallStatus;
                                        switch (x) {
                                            case SerialPortUtils.EM_STATUS_STOP:
                                                delayRun(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        //发送电机启动运行命令
                                                        controlEM(needEMType, SerialPortUtils.EMActionStart);
                                                    }
                                                }, brakeDelay);
                                                break;
                                            case SerialPortUtils.EM_STATUS_WAIT:
                                                delayRun(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        //发送电机由wait转为run
                                                        controlEM(needEMType, SerialPortUtils.EMActionRun);
                                                    }
                                                }, brakeDelay);
                                                break;
                                            case SerialPortUtils.EM_STATUS_RUN:
                                                break;
                                        }
                                        break;
                                }
                                break;
                        }
                        break;
                    }
            }
        } else {
            builder.append("校验失败\n");
            builderW("Test");
        }
    }

    //10秒切换超时计时器相关**************************************************************************
    //计时器（10s读）
    private Timer timer;
    private TimerTask task;
    private int timeOutNum = 0;

    private void initTimer() {
        timer = new Timer();
        task = new TimeOutTask();
    }

    //启动计时器
    private void startTimer() {
        /*
         * java.util.Timer.schedule(TimerTask task, long delay, long period)：
         * 这个方法是说，delay/1000秒后执行task,然后进过period/1000秒再次执行task，
         * 这个用于循环任务，执行无数次，当然，你可以用timer.cancel();取消计时器的执行。
         */
        initTimer();
        try {
            timer.schedule(task, 1000, 1000);
        } catch (IllegalStateException e) {
            e.printStackTrace();
            initTimer();
            timer.schedule(task, 1000, 1000);
        }
    }

    private void autoStopTimer() {
        if (timer != null) {
            timer.cancel();
        }
    }

    private void stopTimer() {
        if (timer != null) {
            timer.cancel();
        }
        //置零
        timeOutNum = 0;
    }

    private void destroyTimer() {
        timer = null;
        task = null;
    }

    protected class TimeOutTask extends TimerTask {

        @Override
        public void run() {
            timeOutNum++;
            if (timeOutNum >= readWaitTime) {
                autoStopTimer();
                String message = "";
                switch (status) {
                    case 1:
                    case 3:
                        message = "切换制动器失败";
                        break;
                }
                //提示用户10s切换失败
                if (isImp()) {
                    ((SwitchEMListener) SwitchEMActivity.this).onSwitch(false, message, runEMType);
                }
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        //当activity不在前台是停止定时
        stopTimer();
    }

    @Override
    public void onDestroy() {
        //销毁时停止定时
        stopTimer();
        destroyTimer();
        super.onDestroy();
    }
}